1. Field of the Invention
This invention relates to the field of object-oriented programming in a computer environment.
2. Background
In multi-threaded computer environments of the prior art, when a thread from a process sends a call to delete an object, that thread typically waits for other threads interacting with that same object to dear. During this waiting period, it is common to have other threads invoking the same object, thus increasing rather than decreasing the number of active threads for that object. There is therefore no guarantee that the object will be deleted at all, let alone in a reasonable amount of time. Also, problems arise in the prior art when more than one thread attempts to delete the object. Typically, each deleting thread waits until the other threads have cleared, thus increasing the number of waiting threads unnecessarily.
Objects are self-contained, clearly defined, software modules that encapsulate procedures, such as business practices, and their data. Communicating with each other through carefully defined interfaces, objects allow complex solutions to be constructed similar to the manner in which computers are manufactured from standardized electronic components. Multiple levels of re-use and standardization are made possible, enabling engineers to produce modules, applications, and entire systems that are highly reusable and leveragable.
Networked object technology allows applications access to objects and their shared services anywhere in the network, substantially independent of where the application or object resides. Networked objects also permit individual objects to be updated without the risk of disrupting the application or business process it models, facilitating the graceful, incremental evolution of complex systems. For example, if a new component fails, the component's predecessor can be re-instated quickly and transparently.
An example of the networked object environment is the CORBA-compliant NEO product family from SunSoft.TM., which provides for sharing of objects across networks and differing computing platforms.
Consisting of over 600 software vendors, developers, and end user organizations, the Object Management Group (OMG) has developed and continues to develop standards for a common architecture supporting heterogeneous, distributed, object-oriented applications. The OMG Common Object Request Broker Architecture (CORBA) is designed to allow different object systems from multiple vendors to interact with each other on a network. The CORBA specification comprises the following four components:
i) An Object Request Broker (ORB) to manage objects in a networked environment; PA1 ii) Interoperability for ORB-to-ORB communications; PA1 iii) Common Object Services (CORBAservices); and PA1 iv) Mappings for commonly used programming languages.
The Network Object Request Broker (ORB) is a CORBA-compliant network-based software system providing for the seamless location and execution of objects through a standard interface protocol, enabling objects and programs to transparenfly interact with each other across the network. The NEO ORB is implemented as one or more multi-threaded UNIX processes, providing scalable performance and availability as needed.
To promote heterogeneous object interoperability, the OMG has provided a portable source code reference implementation of the CORBA 2.0 Internet Inter-ORB Protocol to assist software vendors in testing and delivering OMG-compliant products. The Internet Inter-ORB Protocol (Internet IOP) provides a standardized way of connecting ORBs from different CORBA 2.0 compliant vendors, enabling them to communicate with each other. The current Internet IOP is based on TCP/IP protocols.
The OMG CORBAservices definition describes the basic operations required for building distributed systems with objects, such as naming, events, properties, lifecycle and relationship services.
For different object systems to interact, language independence is a concern. The Interface Definition Language (IDL) enables the separation of interface and implementation, allowing object implementation details to change without compromising the plug-and-play qualities of the object. The OMG IDL is a neutral interface definition of an object's operations, allowing the behavior of the object to be defined in IDL, but accommodating the automated transformation of the interface to the C, C++, Objective C, or Smalltalk languages
A multi-threaded environment, such as that provided by UNIX, is typically used for supporting networked objects. Threads are subprocesses spawned off of larger processes for performing a certain function, e.g. performing a printing process, acting on a database object, etc. By supporting multiple threads, the system can serve many clients and processes simultaneously. This enables the sharing of objects and services on the network. Unfortunately, certain actions performed on an object become more complicated when the object is invoked by more than one thread.
In the CORBA environment, an Object Request Broker Daemon process (ORBD) receives object calls from the client processes registered to it. The ORB daemon then locates the object on the network, and acts as the interface between the client process and the networked object. In the NEO environment, the ORB daemon may activate a NEO object server to act as a further interface for the object which may be a standard NEO object or, in some instances, a legacy process encapsulated in a NEO shell to perform as a NEO object. The NEO object server acts to instantiate the object as is necessary to respond to the calls forwarded by the ORB daemon.
FIG. 3 is a block diagram of a CORBA-compliant networked object system. Multiple threads are represented by elements 300-303, where threads 300-301 are threads spawned from a first client process, Client Process 1, and threads 302-303 are threads spawned from a second client process, Client Process N. As indicated in FIG. 3, a single client process can spawn any number of threads. Each of threads 300-303 is linked to Object Request Broker Daemon (ORBD) process 304. ORBD process 304 is in turn linked to a plurality of object servers represented by object server 305 and object server 307. A second ORBD process, ORBD process 310, is further linked to ORBD process 304. ORBD process 310 could also be coupled to further object servers and/or client processes (not shown). Object server 305 is linked to object 306. Object server 307 is linked to objects 308 and 309.
ORBD process 304 receives object requests in the form of locate calls or requests from client process threads 300-303, and determines which object server is supporting the appropriate object. If the necessary server is not currently running, the server is activated and the object is instantiated. Information on the location of the object is returned in response to the locate call, and further requests between the thread and the object are directed by the location information. The same object can be similarly invoked by locate calls from other threads to establish interaction between the object and all applicable threads concurrently.
ORB daemon 310 may provide a gateway for the networked object environment over a large network such as the Internet and/or it may provide cross-platform interaction by providing a platform dependent interface to clients and object servers in its own domain, while providing a standardized interface to ORBD 304.
Object servers 305 and 307 provide access to objects or object libraries, such as shown by objects 306 and 308-309. Legacy objects, that is those objects comprising stand-alone applications and other objects not originally designed for the networked object environment, are provided with an IDL shell that forms an interface through which the object server can access the functions of the legacy object. As the network is substantially independent of hardware boundaries, the objects and object servers may reside on the same computer as the client processes and the ORB daemon, or they may reside on separate computers within the network. Similarly, the networked object environment is substantially independent of the base level implementation of the network.
As described, in the multi-threaded environment, many threads may concurrently invoke the same object. This can become problematic when, in order to reclaim storage or because the object is no longer valid, etc., one thread wishes to dispose of the object. Disposal of the object is nontrivial due to the number of threads being serviced Abrupt disposal of the object would disrupt the other threads being serviced, complicating the process by requiring further processes for handling client process notification of the disruption and thread recovery. Therefore, in order to avoid disruption of other threads, disposal of the object should take place when the number of threads being serviced by the object is zero. I.e., the disposing thread waits for all other current threads to clear from the object. Unfortunately, in the meantime, more thread invocations for the same object may occur.
FIG. 1 is a flow diagram illustrating the object invoking process. In step 100, a thread obtains the address for an object from the ORB daemon, e.g., via a locate request. In step 101, the thread invokes the object with a method invocation directed to the object's address. In step 102, a branch occurs based on whether the object being invoked is already currently invoked by another thread. If the object is currently invoked, then, in step 104, the active invocation count is incremented by one. If the object is not currently invoked by another thread, then, in step 103, the active invocation count is initialized to reflect the invocation.
Steps 103 and 104 lead into step 105. In step 105, the object serves the thread in the requested manner. In step 106, if the thread is done utilizing the method provided by the object, then the thread, or invocation, exits, and the number of active invocations is decremented by one in step 107. If the thread is not finished utilizing the object, then the process returns to step 105.
In the manner illustrated in FIG. 1, multiple threads may invoke the same object, with successive invocations noted in the active invocation count. As stated previously, while the active invocation count reflects thread activity, the object cannot be disposed without disrupting processes out of hand. FIG. 2 illustrates a process of the prior art for disposing of objects in the multi-threaded environment.
In step 200 of FIG. 2, a thread sends a call to delete the object In subsequent step 201, the number of active invocations for that object, i.e., the current number of threads accessing the object, is queried to determine if disposal can be performed without disrupting other processes. If the number of active invocations is zero, indicating that there are no other process threads accessing the object, then, in step 202, the object is deleted. However, if the current number of active invocations is not zero, then the object cannot be deleted yet. The disposing thread waits for active invocations to exit in step 203, and returns to step 201 to query the number of active invocations. Thus, the object is not deleted until the number of active invocations reaches zero.
While the thread waits to delete the object, the number of active invocations is updated to reflect the completion of active threads and the arrival of new threads as illustrated in FIG. 1. When step 201 finally tests positive for zero active invocations, the object is deleted.
Using the process of FIG. 2 to dispose of objects can result in long delays while the deleting object waits for active invocations to clear. Further, because of the possibility for new thread invocations, there is no guarantee that the deletion process will ever complete. This can result in the continued use of an invalid object and/or the undesired continuing occupation of valuable storage by the undeleted object.
No process exists for the handling of multiple deletion requests in the process of FIG. 2. Deletion requests by subsequent threads are kept waiting, as with the original deletion call, until the active invocations clear. This is unnecessary and undesired as it increases the network overhead to account for the waiting threads in each case.